package com.way.common.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.crypto.SecretKey;
import java.time.Instant;
import java.util.Date;

@Data
@Component
@ConfigurationProperties(prefix = "jwt.token")
public class JwtUtils {

    private long expiration;
    private String secret;
    private String subject;

    private final static SecureDigestAlgorithm<SecretKey, SecretKey> ALGORITHM = Jwts.SIG.HS512;

    /**
     * 生成token
     *
     * @param userId userId
     * @return token
     */
    public String createToken(Long userId) {
        return Jwts.builder()
                .claim("userId", userId)
                .subject(subject)
                .expiration(Date.from(Instant.now().plusSeconds(expiration * 60)))
                .issuedAt(Date.from(Instant.now()))
                .signWith(Keys.hmacShaKeyFor(secret.getBytes()), ALGORITHM)
                .compact();

    }

    /**
     * 解析token
     *
     * @param token token
     * @return Claims
     */
    private Claims parseToken(String token) {
        if (!StringUtils.hasText(token)) {
            return null;
        }
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .verifyWith(Keys.hmacShaKeyFor(secret.getBytes()))
                    .build()
                    .parseSignedClaims(token)
                    .getPayload();
        } catch (ExpiredJwtException e) {
            claims = e.getClaims();
        }
        return claims;
    }

    /**
     * 获取userId
     *
     * @param token token
     * @return userId
     */
    public Long getUserId(String token) {
        Claims claims = parseToken(token);
        if (claims == null) {
            return null;
        }
        Integer userId = (Integer) claims.get("userId");
        return userId.longValue();
    }

    /**
     * 是否过期
     *
     * @param token token
     * @return True过期，False未过期
     */
    public boolean isExpiration(String token) {
        Claims claims = parseToken(token);
        if (claims == null) {
            return true;
        }
        return claims.getExpiration().before(new Date());
    }

}
